#include <linux/module.h>
#include <linux/proc_fs.h>
//#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/uaccess.h>

#define PROC_FILE "nfs_file" //proc文件名称

static char *buf = NULL;
static struct proc_dir_entry *g_pfile;

//proc文件read函数
static ssize_t read_proc(struct file *file, char __user *ubuf, size_t size, loff_t *off){
	int len;

	if(!buf){
		printk("NULL\n");
		return -EFAULT;
	}

	len = strlen(buf);
	//从内核态拷到用户态
	if(0 != copy_to_user(ubuf, buf, len + 1))
		return -EFAULT;

	printk("kernel proc send: %s\n", buf);
	*off = len;
	return len;
}

//proc文件write函数
static ssize_t write_proc(struct file * file, const char __user *ubuf, size_t count, loff_t *off){
	char *tmp;
	int input_c;
       
	//动态保存写入的数据
	tmp = kzalloc(count + 1, GFP_KERNEL);
	if(!tmp)
		return -EFAULT;

	//从用户态拷贝数据
	if(0 != copy_from_user(tmp, ubuf, count)){
		kfree(tmp);
		tmp = NULL;
		return -EFAULT;
	}

	input_c = strlen(ubuf);
	*off = input_c;
	if(buf){
		kfree(buf);
		buf = NULL;
	}
	buf = tmp;
	printk("kernel proc recv: %s\n", buf);

	return input_c;
}

//proc文件操作函数
const struct file_operations file_opt = {
	.read = read_proc,
	.write = write_proc,
	.owner = THIS_MODULE,
};

//模块初始化函数
static int __init proc_init(void){
	//创建内核，应用通信文件
	g_pfile = proc_create(PROC_FILE, 0666, NULL, &file_opt);
	if(!g_pfile){
		printk("can not create /proc/nfs_file\n");
		return -EFAULT;
	}

	printk("procfs.ko insmod success\n");
	return 0;
}

//模块退出函数
static void __exit proc_exit(void){
	//释放相关资源
	if(g_pfile)
		proc_remove(g_pfile);

	if(buf)
		kfree(buf);
	printk("procfs.ko rmmod success\n");
}

module_init(proc_init);
module_exit(proc_exit);
MODULE_AUTHOR("NFS");
MODULE_LICENSE("GPL");
